class Platform:
	def __init__(self,pos,image,xphase=False,yphase=False,xcross=False):
		self.pos=pos
		self.boundedList=[]
		self.image=image
		self.x_phasing=xphase
		self.y_phasing=yphase
		self.enroute=None
		self.x_cross=xcross
	def getWidth(self):
		return self.image.get_width()
	def getHeight(self):
		return self.image.get_height()
	def objectLanding(self,objecto):
		#print 'check',self.__class__.__name__,repr(self.pos)
		if not (self is objecto.x_bound) and (not objecto.y_bound):
			self.yLanding(objecto)
		if not (self is objecto.y_bound) and (not objecto.x_bound):
			self.xLanding(objecto)
	def unbound(self,him):
		self.boundedList.remove(him)
		if him.x_bound is self:
			him.x_bound=None
			him.x_cling=False
			him.checkForCurrentState()
		if him.y_bound is self:
			him.y_bound=None
			him.hangsFromButtom=False
			him.checkForCurrentState()
	
	def process(self):
		pass
	def within_x_boundary(self,ox,ow,k=0.0):
		return self.leftSide()<=ox+k*ow and ox-k*ow<=self.rightSide()
	def isSlim(self):
		return False
	def isThin(self):
		return False
	def to_x_other_side(self,objecto):
		if objecto.facingRight:
			objecto.facingRight=False
			objecto.x=self.rightSide()+0.5*objecto.getWidth()
		else:
			objecto.facingRight=True
			objecto.x=self.leftSide()-0.5*objecto.getWidth()
	
	def within_y_boundary(self,oy,oh):
		return self.lowerSide()<=oy+oh<=self.upperSide()
	def hasFallenOff_y(self,objecto):
		if objecto.y<self.upperSide() and not objecto.hangsFromButtom:
			objecto.y=self.upperSide()
		elif objecto.y+objecto.getHeight()>self.lowerSide() and objecto.hangsFromButtom:
			objecto.y=self.lowerSide()-objecto.getHeight()
		if objecto.y>self.upperSide() or objecto.y+objecto.getHeight()<self.lowerSide():
			self.unbound(objecto)
		elif not self.within_x_boundary(objecto.x,objecto.getWidth()):
			self.unbound(objecto)
	def upperCondition(self,objecto):
		x1=objecto.intermediate_x(self.upperSide())
		#return self.leftSide()<=x1<=self.rightSide() and (objecto.y<=self.upperSide()<=objecto.prev_y+objecto.getHeight())
		return self.within_x_boundary(x1,objecto.getWidth()) and (objecto.y<=objecto.prev_y and objecto.y<=self.upperSide()<=objecto.prev_y+objecto.getHeight())
	def lowerCondition(self,objecto):
		x2=objecto.intermediate_x(self.lowerSide()-objecto.getHeight())
		return self.within_x_boundary(x2,objecto.getWidth()) and (objecto.y>=objecto.prev_y and objecto.prev_y<=self.lowerSide()<=objecto.y+objecto.getHeight())
	def yLanding(self,objecto):
		#x1=objecto.intermediate_x(self.upperSide())
		#x2=objecto.intermediate_x(self.lowerSide()-objecto.getHeight())
		if self.upperCondition(objecto):
			self.reaction_up(objecto)
		elif self.lowerCondition(objecto):
			self.reaction_down(objecto)
	def hasFallenOff_x(self,objecto):
		flag=self.within_y_boundary(objecto.y,objecto.getHeight())
		con1=objecto.x<self.leftSide() and objecto.thereIsNothingElse((self.leftSide()+1,self.upperSide()+1),self)
		con2=objecto.x>self.rightSide() and objecto.thereIsNothingElse((self.rightSide()-1,self.upperSide()+1),self)
		if objecto.x_cling:
			print "cling check"
			if objecto.y+objecto.getHeight()-objecto.x_bound.upperSide()>=objecto.getCrawlHeight():
				print "reposition"
				if objecto.y_bound:
					objecto.y_bound.unbound(objecto)
				yb=objecto.x_bound
				yb.unbound(objecto)
				objecto.crawl=True
				if objecto.facingRight:
					objecto.reposition(yb.leftSide(),yb.upperSide())
				else:
					objecto.reposition(yb.rightSide(),yb.upperSide())
				yb.boundY(objecto,False)
		elif self.clingable() and objecto.y+objecto.getHeight()-self.upperSide()>=0 and (con1 or con2):
			objecto.x_cling=True
			objecto.checkForCurrentState()
		elif flag and objecto.x+0.5*objecto.getWidth()>self.leftSide() and objecto.facingRight:
			objecto.x=self.leftSide()-0.5*objecto.getWidth()
		elif flag and objecto.x-0.5*objecto.getWidth()<self.rightSide() and not objecto.facingRight:
			objecto.x=self.rightSide()+0.5*objecto.getWidth()
		elif not flag or objecto.x+0.5*objecto.getWidth()<self.leftSide() or objecto.x-0.5*objecto.getWidth()>self.rightSide():
			if objecto.canClimb(self) and objecto.y+objecto.getHeight()<self.lowerSide() and (objecto.facingRight and objecto.thereIsNothingElse((self.leftSide(),self.lowerSide()-1),None)):
				print 'slide under 1'
				self.unbound(objecto)
				objecto.reposition(self.leftSide(),self.lowerSide()-objecto.getHeight())
				self.boundY(objecto,True)
			elif objecto.canClimb(self) and objecto.y+objecto.getHeight()<self.lowerSide() and (not objecto.facingRight and objecto.thereIsNothingElse((self.rightSide(),self.lowerSide()-1),None)):
				print 'slide under 2'
				self.unbound(objecto)
				objecto.reposition(self.rightSide(),self.lowerSide()-objecto.getHeight())
				self.boundY(objecto,True)
			else:
				self.unbound(objecto)
	def leftCondition(self,objecto):
		y1=objecto.intermediate_y(self.leftSide()-0.5*objecto.getWidth())
		r=(self.lowerSide()<y1+objecto.getHeight() and y1<self.upperSide()) and objecto.prev_x<=objecto.x and objecto.prev_x<=self.leftSide()<=objecto.x+0.5*objecto.getWidth()
		#print 'left is good?',r
		return r
	def rightCondition(self,objecto):
		y2=objecto.intermediate_y(self.rightSide()+0.5*objecto.getWidth())
		return (self.lowerSide()<y2+objecto.getHeight() and y2<self.upperSide()) and objecto.x<=objecto.prev_x and objecto.x-0.5*objecto.getWidth()<=self.rightSide()<=objecto.prev_x#-0.5*objecto.getWidth()
	def xLanding(self,objecto):
		#y1=objecto.intermediate_y(self.pos[0]-0.5*objecto.getWidth())
		#y2=objecto.intermediate_y(self.pos[0]+self.getWidth()+0.5*objecto.getWidth())
		if self.leftCondition(objecto):
			self.reaction_left(objecto)
		elif self.rightCondition(objecto):
			self.reaction_right(objecto)
	def leftSide(self):
		return self.pos[0]
	def rightSide(self):
		return self.pos[0]+self.getWidth()
	def slideDown(self,him):
		if him.x_cling or him.canClimb(self):
			return 0
		return 1
	def reaction_up(self,objecto):
		x1=objecto.intermediate_x(self.upperSide())
		bumped=objecto.bumping() and self.bumpingAllowed()
		if bumped:
			objecto.bumpY(x1,self.upperSide())
		else:
			objecto.rebound(x1,self.upperSide())
			self.boundY(objecto,False)
	def reaction_down(self,objecto):
		x2=objecto.intermediate_x(self.lowerSide()-objecto.getHeight())
		bumped=objecto.bumping() and self.bumpingAllowed()
		if bumped:
			objecto.bumpY(x2,self.lowerSide()-objecto.getHeight())
		else:
			objecto.rebound(x2,self.lowerSide()-objecto.getHeight())
			if objecto.canClimb(self) and objecto.isAlive():
				self.boundY(objecto,True)
	def reaction_left(self,objecto):
		y1=objecto.intermediate_y(self.leftSide()-0.5*objecto.getWidth())
		bumped=objecto.bumping() and self.bumpingAllowed()
		if bumped:
			objecto.bumpX(self.leftSide()-0.5*objecto.getWidth(),y1)
		else:
			if objecto.isAlive():
				objecto.facingRight=True
				objecto.rebound(self.leftSide()-0.5*objecto.getWidth(),y1)
				self.boundX(objecto,False)
			else:
				objecto.rebound(self.leftSide()-0.5*objecto.getWidth(),y1)#-self.slideDown(objecto))
		
	def reaction_right(self,objecto):
		y2=objecto.intermediate_y(self.rightSide()+0.5*objecto.getWidth())
		bumped=objecto.bumping() and self.bumpingAllowed()
		if bumped:
			objecto.bumpX(self.rightSide()+0.5*objecto.getWidth(),y2)
		else:
			if objecto.isAlive():
				objecto.facingRight=False
				objecto.rebound(self.rightSide()+0.5*objecto.getWidth(),y2)
				self.boundX(objecto,False)
			else:
				objecto.rebound(self.rightSide()+0.5*objecto.getWidth(),y2)#-self.slideDown(objecto))
	def pointOfPlatform(self,x,y):
		#return self.within_x_boundary(x,0) and self.within_y_boundary(y,0)
		return self.leftSide()<=x<=self.rightSide() and self.lowerSide()<=y<=self.upperSide()
	def bumpingAllowed(self):
		return True
	def clingable(self):
		return True
	def boundX(self,objecto,cling):
		self.boundedList.append(objecto)
		objecto.x_bound=self
		objecto.coordDump()
		objecto.x_cling=cling
		objecto.checkForCurrentState()
	def boundY(self,objecto,hang):
		self.boundedList.append(objecto)
		objecto.y_bound=self
		objecto.coordDump()
		objecto.hangsFromButtom=hang
		if hang:
			objecto.crawl=False
		objecto.checkForCurrentState()
	def unboundAll(self):
		boundedList=self.boundedList[:]
		for hero in boundedList:
			self.unbound(hero)